import axios, { AxiosInstance } from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Session } from '/@/utils/storage';
import qs from 'qs';
import router from '/@/router';

// 配置新建一个 axios 实例
const service: AxiosInstance = axios.create({
	baseURL: process.env.NODE_ENV === 'mock' ? '' : import.meta.env.VITE_API_URL,
	timeout: 50000,
	// headers: { 'Content-Type': 'application/json' },
	paramsSerializer: {
		serialize(params) {
			return qs.stringify(params, { allowDots: true });
		},
	},
});

// 添加请求拦截器
service.interceptors.request.use(
	(config: any) => {
		// 在发送请求之前做些什么 token
		// if (Session.get('token')) {
		config.headers = {
			'Content-Type': 'application/json',
			'X-Token': Session.get('token'),
			...config.headers
		}
		// }
		return config;
	},
	(error) => {
		// 对请求错误做些什么
		return Promise.reject(error);
	}
);

// 添加响应拦截器
service.interceptors.response.use(
	response => {
		if (response.status !== 200) {
			return Promise.reject(new Error(response.statusText || 'Error'))
		}
		// 刷新token
		if (response.headers['New-Token']) {
			Session.set('token', response.headers['New-Token'])
		}
		const { data } = response
		switch (data.code) {
			case 0:
				return data
			case -1:
				ElMessage({
					type: 'warning',
					message: data.msg || '警告信息',
				})
				return Promise.reject(response)
			case -2:
				ElMessage({
					type: 'error',
					message: data.msg || '服务器内部错误',
				})
				return Promise.reject(response)
			default:
				return Promise.reject(response)
		}
	},
	(err) => {
		if (err && err.response) {
			switch (err.response.status) {
				case 401:
					err.message = '登录已失效，请重新登录'
					Session.clear(); // 清除浏览器全部临时缓存
					router.push('/login');
					ElMessageBox.alert('你已被登出，请重新登录', '提示', {})
					break
				case 404:
					err.message = `请求地址出错: ${err.response.config.url}`
					break
				default:
					err.message = '网关错误'
					break
			}
			ElMessage.error(err.message)
		} else {
			ElMessage.error('服务器已断开')
		}
		return Promise.reject(err)
	}
);

// 导出 axios 实例
export default service;
